<template>
  <div class="waterfall-container" :style="containerStyle">
    <WaterfallColumn
      v-for="(columnProducts, index) in columns"
      :key="index"
      :products="columnProducts"
      :column-width="columnWidth"
      :gap="gap"
      :min-image-height="minImageHeight"
      :max-image-height="maxImageHeight"
      :show-skeleton="showSkeleton && index < skeletonColumns"
      :skeleton-count="skeletonCount"
      @product-click="handleProductClick"
      @image-load="handleImageLoad"
      @image-error="handleImageError"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, watch, ref, nextTick } from 'vue'
import WaterfallColumn from './WaterfallColumn.vue'
import type { ProductItem } from './ProductWaterfallCard.vue'

// Props
interface Props {
  products: ProductItem[]
  columnCount?: number
  gap?: number
  minImageHeight?: number
  maxImageHeight?: number
  showSkeleton?: boolean
  skeletonCount?: number
  skeletonColumns?: number
}

const props = withDefaults(defineProps<Props>(), {
  columnCount: 2,
  gap: 12,
  minImageHeight: 150,
  maxImageHeight: 300,
  showSkeleton: false,
  skeletonCount: 3,
  skeletonColumns: 2
})

// Emits
const emit = defineEmits<{
  productClick: [product: ProductItem]
  imageLoad: [product: ProductItem]
  imageError: [product: ProductItem]
  layoutComplete: []
}>()

// 响应式数据
const columns = ref<ProductItem[][]>([])
const columnHeights = ref<number[]>([])

// 计算属性
const containerStyle = computed(() => ({
  display: 'flex',
  gap: `${props.gap}px`,
  padding: `0 ${props.gap / 2}px`
}))

const columnWidth = computed(() => {
  return `calc(${100 / props.columnCount}% - ${props.gap}px)`
})

// 监听商品数据变化，重新布局
watch(
  () => props.products,
  (newProducts) => {
    layoutProducts(newProducts)
  },
  { immediate: true, deep: true }
)

// 监听列数变化，重新布局
watch(
  () => props.columnCount,
  () => {
    layoutProducts(props.products)
  }
)

// 方法
function initColumns(): void {
  columns.value = Array.from({ length: props.columnCount }, () => [])
  columnHeights.value = Array.from({ length: props.columnCount }, () => 0)
}

function layoutProducts(products: ProductItem[]): void {
  initColumns()
  
  products.forEach((product) => {
    addProductToColumn(product)
  })
  
  nextTick(() => {
    emit('layoutComplete')
  })
}

function addProductToColumn(product: ProductItem): void {
  // 找到高度最小的列
  const minHeightIndex = columnHeights.value.indexOf(Math.min(...columnHeights.value))
  
  // 将商品添加到该列
  columns.value[minHeightIndex].push(product)
  
  // 估算商品卡片高度（图片高度 + 信息区域高度）
  const estimatedHeight = getEstimatedCardHeight(product)
  columnHeights.value[minHeightIndex] += estimatedHeight
}

function getEstimatedCardHeight(product: ProductItem): number {
  // 估算卡片高度：随机图片高度 + 固定信息区域高度 + 间距
  const randomImageHeight = Math.floor(
    Math.random() * (props.maxImageHeight - props.minImageHeight + 1)
  ) + props.minImageHeight
  
  const infoHeight = 80 // 商品信息区域高度
  const cardGap = 12 // 卡片间距
  
  return randomImageHeight + infoHeight + cardGap
}

function handleProductClick(product: ProductItem): void {
  emit('productClick', product)
}

function handleImageLoad(product: ProductItem): void {
  emit('imageLoad', product)
  // 图片加载完成后可以重新计算布局（可选）
  // rebalanceColumns()
}

function handleImageError(product: ProductItem): void {
  emit('imageError', product)
}

// 重新平衡列高度（可选功能）
function rebalanceColumns(): void {
  // 这里可以实现更精确的列高度平衡算法
  // 例如：获取实际DOM高度来重新分配商品
}

// 暴露方法给父组件
defineExpose({
  rebalanceColumns,
  addProduct: addProductToColumn
})
</script>

<style scoped>
.waterfall-container {
  width: 100%;
  box-sizing: border-box;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .waterfall-container {
    padding: 0 6px;
  }
}

@media (max-width: 480px) {
  .waterfall-container {
    padding: 0 4px;
  }
}
</style>